package me.szlx.region;

import me.szlx.thing.ThingException;
import me.szlx.thing.Trait;
import me.szlx.thing.manager.ThingManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;
import java.util.stream.Collectors;

public abstract class Regions {
    public static final String TRAIT_NAME = "REGION";
    private static final Logger logger = LoggerFactory.getLogger(Regions.class);
    private static RegionManager manager;

    public static Region get(long code) {
        return getManager().get(code);
    }

    public static List<Region> getProvinceList() {
        return getManager().list(Type.PROVINCE.getTrait());
    }

    public static List<Region> getCityList() {
        return getManager().list(Type.CITY.getTrait());
    }

    public static List<Region> getCityList(Region province) {
        List<Region> result = getCityList();
        if (province != null) {
            result = result.stream().filter(city -> city.like(province, Type.PROVINCE.getTrait())).collect(Collectors.toList());
        }
        return result;
    }

    public static List<Region> getDistrictList() {
        return getManager().list(Type.DISTRICT.getTrait());
    }

    public static List<Region> getDistrictList(Region city) {
        List<Region> result = getDistrictList();
        if (city != null) {
            result = result.stream().filter(district -> district.like(city, Type.CITY.getTrait())).collect(Collectors.toList());
        }
        return result;
    }

    public static RegionManager getManager() {
        if (manager == null) {
            useSPI();
        }
        if (manager == null) {
            throw new ThingException("未发现区域管理器");
        }
        return manager;
    }

    private static void useSPI() {
        Iterator<RegionManager> managerIterator = ServiceLoader.load(RegionManager.class).iterator();
        while (managerIterator.hasNext()) {
            RegionManager.use(managerIterator.next());
        }
    }

    public enum Type {
        PROVINCE("province"), CITY("city"), DISTRICT("district");

        private Trait trait;

        Type(String code) {
            this.trait = Trait.create(TRAIT_NAME, code);
        }

        public Trait getTrait() {
            return trait;
        }
    }

    public interface RegionManager extends ThingManager<Region> {
        static RegionManager use(RegionManager manager) {
            RegionManager oldManager = Regions.manager;
            if (manager != null) {
                Regions.manager = manager;
                if (oldManager != null) {
                    logger.debug("区域管理器已被取消：{}", oldManager);
                }
                logger.debug("区域管理器已设置为：{}", manager);
            }
            return oldManager;
        }
    }
}
